import win32con
import win32gui
import win32print


def get_printer_dpi(printer_name=None):
    """获取指定打印机的DPI"""
    if not printer_name:
        printer_name = win32print.GetDefaultPrinter()

    h_printer = win32print.OpenPrinter(printer_name)
    try:
        hdc = win32gui.CreateDC("", printer_name, None)
        horz_dpi = win32print.GetDeviceCaps(hdc, win32con.LOGPIXELSX)
        vert_dpi = win32print.GetDeviceCaps(hdc, win32con.LOGPIXELSY)
        win32gui.DeleteDC(hdc)
        return (horz_dpi, vert_dpi)
    except Exception as e:
        raise e
    finally:
        win32print.ClosePrinter(h_printer)


def get_printer_paper_size(printer_name=None):
    """获取打印机的纸张宽高(mm)"""
    if not printer_name:
        printer_name = win32print.GetDefaultPrinter()

    h_printer = win32print.OpenPrinter(printer_name)
    try:
        hdc = win32gui.CreateDC("", printer_name, None)
        # 获取纸张宽度和高度(单位: mm)
        paper_width = win32print.GetDeviceCaps(hdc, win32con.HORZSIZE)
        paper_height = win32print.GetDeviceCaps(hdc, win32con.VERTSIZE)
        win32gui.DeleteDC(hdc)
        return (paper_width, paper_height)
    except Exception as e:
        raise e
    finally:
        win32print.ClosePrinter(h_printer)


def list_printers():
    """列举所有可用的打印机"""
    return win32print.EnumPrinters(
        win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS
    )


def open_printer_properties(printer_name=None):
    """打开指定打印机的配置页面"""
    if not printer_name:
        printer_name = win32print.GetDefaultPrinter()

    # h_printer = win32print.OpenPrinter(printer_name)

    h_printer = win32print.OpenPrinter(
        printer_name, {"DesiredAccess": win32print.PRINTER_ALL_ACCESS}
    )
    try:
        dev_mode = win32print.GetPrinter(h_printer, 2)["pDevMode"]

        # 调用 DocumentProperties 打开属性对话框（使用 DM_IN_PROMPT | DM_OUT_BUFFER 标志）
        # 正确的参数组合：允许读取现有配置并保存修改后的配置
        result = win32print.DocumentProperties(
            0,
            h_printer,
            printer_name,
            dev_mode,
            dev_mode,
            win32con.DM_IN_PROMPT | win32con.DM_OUT_BUFFER,
        )

        # 保存更改
        if result == win32con.IDOK:
            printer_info = win32print.GetPrinter(h_printer, 2)
            printer_info["pDevMode"] = dev_mode
            win32print.SetPrinter(h_printer, 2, printer_info, 0)
    except Exception as e:
        raise e
    finally:
        win32print.ClosePrinter(h_printer)


# 使用示例
if __name__ == "__main__":
    # 获取默认打印机DPI
    print("DPI:", get_printer_dpi())

    # 获取默认打印机纸张尺寸
    print("Paper size(mm):", get_printer_paper_size())

    # 列举所有打印机
    print("Available printers:")
    for printer in list_printers():
        print(printer[2])  # 打印机名称在元组的第三个位置

    # 打开打印机配置
    open_printer_properties()
